package com.cooper.resource.download;

import java.io.BufferedInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;

import com.cooper.resource.download.DownloadResource.DownloadItem;
import com.cooper.scraper.HttpDownload;
import com.cooper.scraper.R;

import android.util.Log;

public class BlockDownThread extends DownThread {

	private long startPos = 0;

	public BlockDownThread(HttpDownload httpDownload,
			DownloadStatus downloadStatus, DownloadItem item) {
		super(httpDownload, downloadStatus, item);
		this.startPos = item.getStartPos();
		downLength = item.getDownLength();
	}

	@Override
	protected void runDownload() {
		if (Thread.currentThread().isInterrupted()) {
			return;
		}
		int failType = DownloadStatus.FAIL_FOR_DOWNLOADING;
		int reason = R.string.download_fail;
		try {
			download();
			if (downLength >= item.getFileSize()) {
				item.setFinish(true);
				downloadStatus.saveDownInfo();
				Log.d("BlockDownThread", "DownThread is complete!");
				return;
			}
			Log.d("BlockDownThread", "size is not complete.");
		} catch (FileNotFoundException e) {
			failType = DownloadStatus.FAIL_FOR_FILE_NOT_FOUND;
			Log.e("BlockDownThread", "FileNotFoundException", e);
		} catch (IOException e) {
			if (e.getMessage().equals("No space left on device")){
				failType = DownloadStatus.FAIL_FRO_NO_SPACE;
				reason = R.string.download_fail_for_no_space;
			}
			Log.e("BlockDownThread", e.getMessage(), e);
		} catch (Exception e) {
			Log.e("BlockDownThread", e.getMessage(), e);
		}
		if (!Thread.currentThread().isInterrupted() && !downloadStatus.downFail(reason,failType)) {
			// end pos
			startPos = downLength;
			try {
				sleep(10000);
				runDownload();
			} catch (InterruptedException e1) {
				Log.d("BlockDownThread", "Thread is Trim", e1);
			}
		}
	}

	private void download() throws IOException {
		HttpURLConnection conn = httpDownload.createDefaultConn(item.getUrl());
		try {
			conn.setRequestProperty("Range", "bytes=" + startPos + "-");
			Log.d("DownloadBlockThread", "Thread start download from position "
					+ startPos + ";size:" + item.getFileSize() + ",downLen:"
					+ item.getDownLength());
			InputStream inStream = new BufferedInputStream(
					conn.getInputStream(), STREAM_BUFFER_SIZE);
			try {
				byte[] buffer = new byte[1024];

				RandomAccessFile fos = new RandomAccessFile(
						item.getTargetFilePath(), "rwd");
				try {
					if (startPos > 0)
						fos.seek(startPos);
					int offset = 0;
					while (!Thread.currentThread().isInterrupted()
							&& (offset = inStream.read(buffer, 0, 1024)) != -1) {
						fos.write(buffer, 0, offset);
						// Log.d("BlockDownThread","getData....");
						if (!Thread.currentThread().isInterrupted()) {
							downLength += offset;
							downloadStatus.updateDownLen();
							item.setDownLength(downLength);
						} else {
							return;
						}
					}
				} finally {
					fos.close();
				}
			} finally {
				inStream.close();
			}
		} finally {
			conn.disconnect();
		}

	}

}
